// 构造函数
function One(x, y) {
    this.x = x
    this.y = y
}
One.prototype.init = function () {
    console.log("你好我是谁.")
}

let one = new One()

// one.init() //你好我是谁

// 现在解释一下 new过程的函数发什么了那些变化.
// 主要是理解个过程
function Two(x, y) {
    const temp = {}
    // 让this绑定这个对象
    this = temp
    // 让__proto__指向构造函数的prototype
    this.__proto__ = Two.prototype
    // 隐式的返回 this
    return this // 不用写的
    // 如果显式的返回一个对象那么就会造成把this丢掉
    return { name: "孙文" }
    // return 非对象, 直接丢弃. 还是返回this

}
// 如果显式的返回一个对象那么就会造成把this丢掉
; (function () {
    function One(x, y) {
        this.x = x
        this.y = y
        return { name: "孙文" }
    }
    One.prototype.init = function () {
        console.log("你好我是谁.")
    }

    let one = new One()

    one.init() //one.init is not a function
    console.log(one) //{ name: '孙文' }
})();

// 第二个版本解释new的过程 这个模拟的更完善
; (function () {
    //return
    function Otaku () {
        // ……
    }
    
    // 使用 new
    var person = new Otaku();
    // 使用 objectFactory
    var person1 = objectFactory(Otaku)
    
    // 2.1版本
    function objectFactory() {

        var obj = new Object(),
            // 这个是拿传进来的第一个参数,也就是构造函数, 也改变了arguments
            Constructor = [].shift.call(arguments);

        obj.__proto__ = Constructor.prototype;
        //arguments其实已经全是参数,
        Constructor.apply(obj, arguments);

        return obj;

    };

    // 2.2版本
    // 有返回值效果实现
    // 第二版的代码
    function objectFactory() {

        var obj = new Object(),

        Constructor = [].shift.call(arguments);

        obj.__proto__ = Constructor.prototype;

        var ret = Constructor.apply(obj, arguments);
        // 就是判断一下,构造函数返回的是不是对象, 如果是就返回, 不是就返回obj
        return typeof ret === 'object' ? ret : obj;

    };

})();

